One of the techniques for achieving high scalability for Internet content (e.g., streaming media) is using cache proxies that are distributed near the network endpoints. The operators of such network cache proxies are known as a Content Delivery Network (CDN) or Edge Cache Network (ECN) providers. A CDN is a network of tiered cache nodes that can be used to distribute content delivery. A CDN is most commonly used to reduce the network bandwidth and load on an origin server (or servers) from which the content originates, increase the response time of content delivery, and reduce latency. A CDN tries to accomplish these objectives by serving the content from a cache node that is closest to a user that has requested the content. Each caching layer serves as a “filter” by caching and serving the requested content without having to go to the origin server (such as a web server) for every request.
The Internet has built up a large infrastructure of routers and proxies that are effective at caching data for hypertext transfer protocol (HTTP). Servers can provide cached data to clients with less delay and by using fewer resources than re-requesting the content from the original source. For example, a user in New York may download a content item served from a host in Japan, and receive the content item through a router in California. If a user in New Jersey requests the same file, the router in California may be able to provide the content item without again requesting the data from the host in Japan. This reduces the network traffic over strained routes, and allows the user in New Jersey to receive the content item with less latency.
When caching a content response that has resulted from a request with a query string, the cache node (or the cache proxy) does not know whether to treat the content as a unique content response or not. This is partly because the cache proxy uses the uniform resource locator (URL) as the key to store the cached content, but the query string portion of the URL may refer to dynamic content (that should not be cached), tracking information (that is irrelevant to cache), or static content (that should be cached). Consider the following requests: “http://contoso.com/myapp?a=1&b=2” and “http://contoso.com/myapp?b=2&a=1.” Both are the same request and they result in the same content response. However, because of the ordering of the name-value pairs in the query string (“a” comes before “b” in the first case and “b” comes before “a” in the second case), they are treated as two different “keys” by the cache proxy. The result is that the same content is cached twice, wasting disk space and other resources of the cache proxy. Also consider the following requests: “http://contoso.com/myapp?a=1&b=2&c=3,” “http://contoso.com/myapp?a=1&b=2&c=,” and “http://contoso.com/myapp?a=1&b=2.” Depending on how “myapp” uses the value for “c,” each of these requests may result in the same response, but they will result in three separate cached objects on the cache proxy. The problem worsens when query string is used for user tracking purposes. For example, consider “http://contoso.com/myimage.jpg?sessionID=23e98348791384723049580193448,” where each session is assigned a different session identifier.
Some cache proxies solve this problem by ignoring the query string completely. However, this solution results in responses other than what the web content author intended. In fact, depending on which requests come in first and which of multiple cache proxies respond to the requests, users whose requests happen to go through different cache proxies can receive different responses for the same request. This is generally an unacceptable user experience.